        SUBT    > Sources.FileTypes

; This file contains file type manipulation routines:

; IsFileTyped
; ExtractFileTypes
; FileTypeToifscb
; AdjustObjectTypeReMultiFS
; ComplexAdjustObjectTypeReMultiFS

; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
; IsFileTyped
;
; In    r2 = load address
;       r3 = execute address
;
; Out   EQ it is a file typed pair
;       NE they're a load and execute address - honest!
;
; A file is not date stamped if:
; load          exec    Meaning
; 0             -1      A command file
; -1            -1      A command file
; < &FFF000000   *       Load/execute address pair
; nnnn          nnnn    (load = exec) probably &ffff0900 for BBCs
;
IsFileTyped ROUT

        ; Check for (0,-1) and (-1,-1)
        TEQ     r2, #0
        CMPNE   r2, #-1
        CMPEQ   r3, #-1
        TEQNE   r2, r3          ; Check for load=exec
        BICEQS  pc, lr, #Z_bit

        ; Check for load < &fff00000
        CMP     r2, #&fff00000
        BICLOS  pc, lr, #Z_bit

        ; load >= &fff00000 hence date stamped
        ORRS    pc, lr, #Z_bit

; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
; ExtractFileType
;
; In    r2 = load address of a known typed file
;
; Out   r2 = file's type
;
ExtractFileType ROUT

        MOV     r2, r2, ASL #12         ; Junk 12 bits to the left
        MOV     r2, r2, LSR #8+12       ; and 8 bits to the right

        MOV     pc, lr

; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
; FileTypeToifscb
;
; In    r2 = filetype
;
; Out   r1 = fscb and EQ or Nowt and NE
;
; This routine takes a filetype and tries to find it in the list of
; registered MultiFS filing systems.
;
FileTypeToifscb ROUT
        Push    "lr"

        ADR     r1, fschain - fscb_link

10
        LDR     r1, [r1, #fscb_link]
        TEQ     r1, #Nowt
        Pull    "lr", EQ
        BICEQS  pc, lr, #Z_bit

        ; Skip non-MultiFS fscbs
        LDRB    r14, [r1, #fscb_info]
        TEQ     r14, #0
        BNE     %BT10

        LDR     r14, [r1, #fscb_FileType]
        TEQ     r14, r2
        BNE     %BT10

        Pull    "lr"
        ORRS    pc, lr, #Z_bit

; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
; AdjustObjectTypeReMultiFS
;
; In    r0 = Raw object type
;       r2 = load address
;       r3 = execute address
;
; Out   r0 = Adjusted object type
;       r2 = unchanged
;       r3 = unchanged
;
AdjustObjectTypeReMultiFS ENTRY "r1,r2"

        ; Is it a file?
        TEQ     r0, #object_file
        EXITS   NE

        ; Does it have a file type?
        BL      IsFileTyped
        EXITS   NE

        ; Is it a MutliFS file type?
        BL      ExtractFileType
        BL      FileTypeToifscb
        MOVEQ   r0, #object_file :OR: object_directory
        EXITS

; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
; ComplexAdjustObjectTypeReMultiFS
;
; In    r0 = Raw object type
;       r1 = path tail
;       r2 = load address
;       r3 = execute address
;       fscb (may be Nowt)
;       V and globalerror set (possibly)
;
; Out   r0 = Adjusted object type
;       r2 = unchanged
;       r3 = unchanged
;
; Adjusts the following cases:
;       objecttype      mapping
;
;       file            if typed and type==a MultiFS partition
;                               then map to object_file :OR: object_directory
;
;       neither file    if name == <blah>$ except if object_nothing on openalways filing system
;       nor directory           then map to object_directory
;
;       any             if error==not found
;                               then map to object_notfound
;
ComplexAdjustObjectTypeReMultiFS ENTRY "r1,r2"

        BVS     %FT50

05
        ; re-entry point for remapped 'not found' errors

        ; Is it a file?
        TEQ     r0, #object_file
        BNE     %FT10

        ; Does it have a file type?
        BL      IsFileTyped
        EXITS   NE

        ; Is it a MutliFS file type?
        BL      ExtractFileType
        BL      FileTypeToifscb
        MOVEQ   r0, #object_file :OR: object_directory
        EXITS

10
        ; not a file...
        TEQ     r0, #object_directory
        EXITS   EQ

        ; and not a directory

        ; If not there on an openalways filing system, then accept that in any case
        TEQ     r0, #object_nothing
        BNE     %FT15
        TEQ     fscb, #Nowt
        EXIT    EQ
        LDR     lr, [fscb, #fscb_info]
        TST     lr, #fsinfo_alwaysopen
        EXIT    NE

15
        ; otherwise is it $?
        BL      strlen
        SUBS    r3, r3, #1
        BMI     %FT20
        LDRB    lr, [r1, r3]
        TEQ     lr, #"$"

        ; If EQ, then $ returned neither file nor directory, so fake up 'existing directory'
        MOVEQ   r0, #object_directory
        LDREQ   r2, =&fffffd00
        MOVEQ   r3, #0
        TEQNE   r0, #object_nothing
        EXITS   EQ

20
        ; bad object type returned, and its not '$', so there's no excuse!
        ; BARF NOW!
        addr    r0, ErrorBlock_BadFileType
        BL      CopyError
        EXIT

50
        ; VS returned - check for 'Not found' error and remap to object_notfound
        LDR     lr, globalerror
        LDR     lr, [lr]
        BIC     lr, lr, #&ff00          ; remove FS number
        EOR     lr, lr, #&10000         ; top half of TEQ
        TEQ     lr, #ErrorNumber_FileNotFound
        MOVEQ   lr, #0
        STREQ   lr, globalerror
        MOVEQ   r0, #object_nothing
        BEQ     %BT05

        EXITS

        LTORG

        END
